package com.dashu.core.service;

import com.dashu.base.enums.ReplRyCode;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.core.dto.company.CompanyDTO;
import com.dashu.core.dto.gate.GateDateDTO;
import com.dashu.core.dto.gate.GateInTimeDTO;
import com.dashu.core.handler.VerificationException;
import com.dashu.core.model.GateInTime;
import com.dashu.core.model.QGateInTime;
import com.dashu.core.vo.UpdateEntityVO;
import com.dashu.core.vo.gate.GateInTimeVO;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class GateInTimeService extends DataService {
    @Autowired
    private GateDateService gateDateService;
    @Autowired
    private CompanyService companyService;

    @Transactional
    public GateInTimeDTO add(GateInTimeVO gateDateVO) {
        GateInTime gateInTime = CopyUtil.copyEnty(gateDateVO, GateInTime.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            gateInTime.setCreateUser(userId);
            gateInTime.setBaseId(userId);
            entityManager.persist(gateInTime);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        GateInTimeDTO gateDateDTO = CopyUtil.copyEnty(gateInTime, GateInTimeDTO.class);
        return gateDateDTO;

    }

    @Transactional
    public GateInTimeDTO addDefult(long baseId) {
        GateInTime gateInTime = new GateInTime();
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            gateInTime.setId(UIDUtil.nextId());
            gateInTime.setCreateUser(userId);
            gateInTime.setCreateTime(System.currentTimeMillis());
            gateInTime.setBaseId(baseId);
            gateInTime.setIsDefult(0);
            gateInTime.setStartDate1("08:00");
            gateInTime.setEndDate1("11:00");
            gateInTime.setStartDate2("14:00");
            gateInTime.setEndDate2("18:00");
            gateInTime.setStartDate3("19:00");
            gateInTime.setEndDate3("21:00");
            gateInTime.setName("默认考勤");
            gateInTime.setOpen("1,1,1");
            entityManager.persist(gateInTime);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        GateInTimeDTO gateDateDTO = CopyUtil.copyEnty(gateInTime, GateInTimeDTO.class);
        return gateDateDTO;

    }


    @Transactional
    public boolean deleteGateData(long timeId) {
        QGateInTime qGateInTime = QGateInTime.gateInTime;
//        List<GateDateDTO> gateDateDTOS = gateDateService.deleteGateData(timeId);
//        if (gateDateDTOS.size() > 0)
//            throw new VerificationException(ReplRyCode.ATTENDANCE_RULE_TIME, ReplRyCode.ATTENDANCE_RULE_TIME.getMessage());
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qGateInTime.id.eq(timeId));

        List<GateInTime> gateInTimes =
                queryFactory
                        .select(qGateInTime)
                        .from(qGateInTime)
                        .where(booleanBuilder.getValue())
                        .fetch();
        gateInTimes.stream().forEach(ad -> {
            entityManager.remove(ad);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        });
        return true;

    }

    @Transactional
    public GateInTimeDTO updataGateData(UpdateEntityVO<GateInTimeVO> gateDateVO) throws Exception {
        QGateInTime qGateInTime = QGateInTime.gateInTime;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        GateInTimeVO gateInTimeVO = gateDateVO.getEntityVO();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qGateInTime.id.eq(gateDateVO.getId()));
        GateInTime gateInTime =
                queryFactory
                        .select(qGateInTime)
                        .from(qGateInTime)
                        .where(booleanBuilder.getValue())
                        .fetchOne();
        if (gateInTime == null)
            throw new VerificationException(ReplRyCode.ATTENDANCE_NOT_TIME, ReplRyCode.ATTENDANCE_NOT_TIME.getMessage());
        if (gateInTimeVO.getStartDate1() != null)
            gateInTime.setStartDate1(gateInTimeVO.getStartDate1());
        if (gateInTimeVO.getStartDate2() != null)
            gateInTime.setStartDate2(gateInTimeVO.getStartDate2());
        if (gateInTimeVO.getStartDate3() != null)
            gateInTime.setStartDate3(gateInTimeVO.getStartDate3());
        if (gateInTimeVO.getEndDate1() != null)
            gateInTime.setEndDate1(gateInTimeVO.getEndDate1());
        if (gateInTimeVO.getEndDate2() != null)
            gateInTime.setEndDate2(gateInTimeVO.getEndDate2());
        if (gateInTimeVO.getEndDate3() != null)
            gateInTime.setEndDate3(gateInTimeVO.getEndDate3());
        if (!StringUtils.isEmpty(gateInTimeVO.getOpen()))
            gateInTime.setOpen(gateInTimeVO.getOpen());
        gateInTime.setUpdateUser(userId);
        gateInTime.setUpdateTime(new Date().getTime());
        gateInTime = entityManager.merge(gateInTime);
        entityManager.setFlushMode(FlushModeType.AUTO);
        GateInTimeDTO CompanyClsDTO = CopyUtil.copyEnty(gateInTime, GateInTimeDTO.class);
        return CompanyClsDTO;

    }


    public GateInTimeDTO findGateGroup(long timeId) {
        QGateInTime qGateInTime = QGateInTime.gateInTime;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qGateInTime.id.eq(timeId));
        GateInTime gateInTime =
                queryFactory
                        .select(qGateInTime)
                        .from(qGateInTime)
                        .where(booleanBuilder.getValue())
                        .fetchOne();
        GateInTimeDTO gateInTimeDTO = CopyUtil.copyEnty(gateInTime, GateInTimeDTO.class);
        return gateInTimeDTO;

    }

    public long count(String timeName) throws Exception {
        QGateInTime qGateInTime = QGateInTime.gateInTime;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qGateInTime.createUser.eq(userId));
        if (!StringUtils.isEmpty(timeName))
            booleanBuilder.and(qGateInTime.name.eq(timeName));
        long count =
                queryFactory
                        .select(qGateInTime)
                        .from(qGateInTime)
                        .where(booleanBuilder.getValue())
                        .fetchCount();
        return count;

    }

    public List<GateInTimeDTO> findByBaseUser(String timeName) throws Exception {
        QGateInTime qGateInTime = QGateInTime.gateInTime;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qGateInTime.createUser.eq(userId));
        if (!StringUtils.isEmpty(timeName))
            booleanBuilder.and(qGateInTime.name.like("%"+timeName+"%"));

        List<GateInTime> gateInTimes =
                queryFactory
                        .select(qGateInTime)
                        .from(qGateInTime)
                        .where(booleanBuilder.getValue())
                        .fetch();
        List<GateInTimeDTO> gateInTimeDTOS = CopyUtil.copyList(gateInTimes, GateInTimeDTO.class);
        gateInTimeDTOS.stream().forEach(gtd -> {
            CompanyDTO companyDTO = companyService.findByCompanyId(gtd.getBaseId());
            gtd.setName(companyDTO.getCompanyName());
        });
        return gateInTimeDTOS;

    }

}
